如何将软件包发布到映像包管理系统

OTN 系统管理员和开发人员社区上机操作
 

反馈按钮

本上机操作课程将向您介绍映像包管理系统 (IPS) 的各种概念、系统软件管理过程以及以 IPS 格式发布自己的软件包的过程。(有关 IPS 和 Oracle Solaris 11 的更多信息请访问这里。



先决条件

  • 学员已在 Oracle VM VirtualBox 中安装 Oracle Solaris 11。 

本上机操作假定您拥有以下技术的一些基本知识或编程经验。

  • Solaris 操作环境的基本知识
  • C 编程语言和脚本语言的基本知识
  • 支持的操作系统:Oracle Solaris 11
  • 内存要求:推荐 1GB
  • 额外的磁盘空间要求:150 MB(如果使用 VirtualBox,则主机上需要 8GB 的磁盘空间)

本上机操作需要的其他软件:

  • GNU C 编译器。要安装该编译器,您需要准备好 root 口令,然后运行“sudo pkg install gcc-3

上机操作练习

  1. IPS 简介
  2. 使用 IPS 命令
  3. 创建自己的本地 IPS 信息库
  4. 打包一个简单的应用程序并将其提交到 IPS 信息库

练习 1:IPS 简介

预计所需时间:20 分钟

简介

Oracle Solaris 11 采用了一种新的软件包管理方法,极大简化了补丁与更新管理过程,降低了操作系统维护风险。在 Solaris 11 中,我们引入了映像包管理系统 (IPS) 以取代 Oracle Solaris 早期版本中使用的旧式 SVR4 软件包。IPS 极大简化了软件生命周期管理,旨在对整个软件生命周期进行管理,执行软件打包、部署和安装、更新、系统升级以及软件包删除。IPS 还与 ZFS 紧密集成,并使用 ZFS 的特性(如快照和克隆)来最大程度减少与维护有关的风险和停机时间。

IPS 大图

IPS 术语

我们首先需要了解 IPS 中使用的术语和概念。

IPS 软件包

IPS 以软件包为单位对软件进行管理。IPS 软件包是具有明确格式的目录、文件、链接、驱动程序、依赖项、组、用户和许可信息的集合。此集合代表软件包的可安装对象。软件包有软件包名称和描述等属性。

您可以使用命令查看有关软件包的信息,也可以查看软件包的清单

Oracle Solaris 11 同时支持 IPS 软件包和 SVR4 软件包。

尽管大多数管理员可以从软件包信息库安装软件,但也可以从磁盘上 IPS 软件包格式 .p5p 安装软件。这等同于 .rpm、SVR4 软件包或 .nbm 文件。

从开发人员的角度来看,IPS 软件包由一系列操作组成;在软件包清单中对操作进行描述。操作用于定义软件包的文件和目录、设置软件包属性、声明对其他软件包的依赖关系、创建用户和组以及安装设备驱动程序。操作表示系统上的可安装对象。每个操作主要由操作名称及一个关键属性组成。按照版本历史,这些共同指向一个唯一的对象。

每个 IPS 软件包由一个故障管理资源标识符 (FMRI) 表示。pkg(1) 命令使用有效的 FMRI 软件包信息执行其命令操作。FMRI 包括有关软件包的描述性信息,如软件包的发布者、软件包名称、版本信息以及日期。

例如,FMRI pkg://solaris/system/library@0.5.11,5.11-0.175.0.0.0.2.1:20111019T082311Z 由以下信息串接组成:

  • 模式 — pkg
  • 发布者 — solaris
  • 类别 — system
  • 软件包名称 — library
  • 版本字符串 — 由 4 部分组成:
    • 组件版本 — 5.11
    • 内部版本 — 5.11
    • 分支版本 — 175.0.0
    • ISO-8601 基本格式的时间戳 — 20111019T082311Z

IPS 发布者和信息库

  • 发布者是发布软件包的人、人群或企业。
  • 信息库或 depo 服务器是可以下载软件包的位置。例如: http://pkg.oracle.com/solaris/release
  • 一个信息库可以包含来自许多发布者的软件包。反过来,许多信息库可以包含来自一个发布者的软件包。
  • 默认或首选发布者类似于默认目录。首先在首选发布者目录中搜索选定安装的任何软件包。不同信息库也可能提供同名的软件包的下载。

IPS 映像和引导环境

映像是系统上可以安装软件包及其关联文件、目录、链接和依赖项的位置。
映像可以是以下三种类型之一:

  • 完整映像 — 能够提供整个系统。
  • 区域映像 — 链接至完整映像(父映像)以确保软件与全局区域中安装的相一致
  • 用户映像 — 仅包含可重定位的软件包。举例来说,用户映像可以是 Glassfish 3 安装,它在多个平台上使用 IPS。

在系统上完成 Oracle Solaris 11 安装之后,会自动为您提供一个映像。您无需显式创建映像即可安装软件包。但为了提供不同软件应用程序的逻辑分离,必须创建映像,在使用区域时尤其需要如此。

下图说明映像的概念。

映像的概念

pkg(1) 设计为与 Solaris 上的 ZFS 和引导管理紧密集成,它使用 ZFS 快照帮助在软件包安装失败或导致非预期的环境时提供回滚功能。IPS 对要更新的软件执行分析,如果认为有必要(在“pkg update”序列期间),会自动创建一个新的引导环境 (BE),作为将要安装更新软件包版本的位置。新的 BE 将在重新引导时激活,旧的 BE 将用作回滚备用环境,以备升级导致系统不能工作或功能破坏时使用。(beadm 命令可用于列出和控制 Solaris 11 上引导环境的行为)

有关 BE 的详细信息,请参见管理 Oracle Solaris 11 中的引导环境指南。

软件包变体和选件

软件可以具有可选组件和互斥组件。可选组件的例子包括区域设置文档。互斥组件的例子包括 SPARCx86 以及调试非调试 二进制文件。在 IPS 中,可选组件称为选件 (facet),互斥组件称为变体。变体和选件均显示为 IPS 操作的标记。

变体和选件影响是否针对安装选择或取消选择特定操作。

下表显示选件和变体标记及其可能值的一些示例。

名称
facet.locale.*true、false
facet.doc.mantrue、false
facet.doctrue、false
facet.devel.*true、false
variant.archsparc、i386、zos
variant.debug.*true、false

默认情况下,将包括未使用选件也未使用变体进行标记的操作。

排除了使用未选择的变体进行标记的操作。

如果未选定任何选件,将排除使用一个或多个选件进行标记的操作。

  • 使用逻辑“AND”计算变体标记。如果有任何变体标记不匹配,则不安装该操作。
  • 使用逻辑“OR”计算选件标记。如果任何选件标记匹配,则不排除该操作。

单个操作可以有多个选件和变体标记。开发人员所用的架构特定的标头文件就是一个带有多个选件和变体标记的组件示例。

在映像级别设置变体和选件。变体设置为特定属性的映像只能具有与映像上安装的变体匹配的操作。例如,不能将 x86 软件包安装到 SPARC 映像中。

IPS 命令

  • pkg(1)
    • 使用 pkg(1) 命令可创建映像、将软件包安装到映像中以及管理映像上的软件包。
  • pkgdepend(1)
    • pkgdepend(1) 用于生成和解析软件包的依赖关系。一个软件包可能依赖于其他软件包中的文件。
      pkgdepend(1) 通常用于两个过程:
      • 文件依赖关系生成
      • 文件到软件包解析。
  • pkgmogrify(1)
    • pkgmogrify(1) 用于转换使用 pkgdepend(1) 生成的原始清单文件
  • pkgsend(1)
    • pkgsend(1) 命令用于将软件包从映像发布到现有信息库。
  • pkgrecv(1)
    • pkgrecv(1) 命令用于从服务器下载软件包内容。用户可以使用 pkgrecv(1) 将检索到的软件包自动重新发布到本地信息库。另外,用户也可以通过添加其他软件包属性修改内容并使用 pkgsend(1) 命令重新发布软件包。
  • pkgrepo(1M)
    • pkgrepo(1M) 命令用于创建和管理本地信息库的存储和属性。
  • pkg.depotd(1M)
    • pkg.depotd(1M) 后台程序用于运行自己的网络信息库或安装镜像信息库。

IPS GUI 工具

在客户端,IPS 有一个名为“Package Manager”的图形前端。通过“Package Manager”,您可以搜索、安装、更新和删除软件包,管理信息库,还可以管理引导环境。

Package Manager

IPS 还提供了一个 Update Manager。Update Manager 是一个桌面应用程序,允许用户更新映像中安装的所有软件包,当安装的软件包有可用更新时,Update Manager 会通知用户。

 Update Manager

练习 2:使用 IPS 命令

为熟悉 IPS 的使用,我们先来熟悉一下 IPS 命令。

管理发布者/信息库

列出当前软件包发布者

oracle@solaris:~$ pkg publisher
PUBLISHER            TYPE     STATUS   URI
solaris (preferred)  origin   online   http://pkg.oracle.com/solaris/release/

添加其他软件包发布者 

oracle@solaris:~$ sudo pkg set-publisher -g  http://pkg.sunfreeware.com:9001 sunfreeware.com Password:
oracle@solaris:~$ pkg publisher
PUBLISHER            TYPE     STATUS   URI
solaris (preferred)  origin   online   http://pkg.oracle.com/solaris/release/ sunfreeware.com                       
                     origin   online   http://pkg.sunfreeware.com:9001/

因为现在不需要,我们来删除它。

oracle@solaris:~$ sudo pkg unset-publisher sunfreeware.com
Password:
oracle@solaris:~$ pkg publisher
PUBLISHER            TYPE     STATUS   URI
solaris (preferred)  origin   online   http://pkg.oracle.com/solaris/release/

如何搜索软件包

在已安装映像中搜索软件包。以下示例搜索和定位 bash 命令 gperf,让我们知道该命令来自哪个软件包。


oracle@solaris:~/Work/srm-1.2.10$ pkg search gperf
INDEX           ACTION VALUE                     PACKAGE
basename        file   usr/bin gperf             pkg:/developer/gperf@3.0.3-0.175.0.0.0.2.537
pkg.description set    GNU gperf is a perfect hash function generator. For a given list of strings, 
                       it produces a hash function and hash table, in form of C or C++ code, 
                        for looking up a value depending on the 
                       input string.
                                                 pkg:/developer/gperf@3.0.3-0.175.0.0.0.2.537
pkg.fmri        set    solaris/developer/gperf   pkg:/developer/gperf@3.0.3-0.175.0.0.0.2.537
pkg.summary     set    GNU gperf                 pkg:/developer/gperf@3.0.3-0.175.0.0.0.2.537
basename        dir    usr/share/doc/gperf       pkg:/developer/gperf@3.0.3-0.175.0.0.0.2.537

在远程信息库中搜索软件包。在与当前映像关联的远程 (-r) 信息库中搜索 bash 软件包:

oracle@solaris:~/Work/srm-1.2.10$ pkg search -r bash
INDEX      ACTION VALUE              PACKAGE
basename   file   usr/bin/bash       pkg:/shell/bash@4.1.9-0.175.0.0.0.2.537
pkg.fmri   set    solaris/shell/bash pkg:/shell/bash@4.1.9-0.175.0.0.0.2.537
basename   dir    etc/bash           pkg:/shell/bash@4.1.9-0.175.0.0.0.2.537
basename   dir    usr/share/bash     pkg:/shell/bash@4.1.9-0.175.0.0.0.2.537

如何安装软件包

本示例安装 gperf。输出显示下载的状态、已安装的软件包数、已安装的文件数及下载的大小 (MB)。

oracle@solaris:~/Work/srm-1.2.10$ sudo pkg install gperf
           Packages to install:  1
       Create boot environment: No
Create backup boot environment: No
            Services to change:  1

DOWNLOAD                    PKGS  FILES    XFER (MB)
Completed                   1/1   8/8      0.1/0.1

PHASE                       ACTIONS
Install Phase               27/27

PHASE                       ITEMS
Package State Update Phase  1/1
Image State Update Phase    2/2

oracle@solaris:~/Work/srm-1.2.10$ pkg list gperf
NAME (PUBLISHER)            VERSION                    IFO
developer/gperf             3.0.3-0.175.0.0.0.2.537    i--

如何卸载软件包

本示例卸载 gperf 软件包。

oracle@solaris:~/Work/srm-1.2.10$ sudo pkg uninstall gperf
Packages to remove:     1
Create boot environment:    No
PHASE                         ACTIONS
Removal Phase                 21/21

PHASE                         ITEMS
Package State Update Phase    1/1
Package Cache Update Phase    1/1
Image State Update Phase      2/2

PHASE                         ITEMS
Reading Existing Index        8/8
Indexing Packages             1/1
oracle@solaris:~/Work/srm-1.2.10$ pkg list gperf
pkg list: no packages matching 'gperf' installed

总结

现在,您应对 IPS 软件包管理系统有了一个基本的了解


练习 3:创建自己的本地 IPS 信息库

预计所需时间:20 分钟

简介:

我们将查看两个启用本地信息库的方法。首先我们将看看如何创建一个可以直接通过 IPS 客户端命令访问的基于文件的信息库。其次,在此之后,我们通过 pkg 服务器将其作为网络服务实例化到信息库,允许通过网络进行访问。这两种方法均可以用于开发和测试。但如果您希望在自己的系统上永久运行信息库服务器,建议 (a) 准备足够的磁盘空间在本地磁盘上存放文件,并且 (b) 使用 SMF 管理信息库服务器,信息库服务器服务的默认 SMF FMRI 是 svc:/application/pkg/server

这可以通过两种方式来完成,最简单的方式只需修改信息库服务默认实例的属性以反映配置,这正是我们将在本上机操作练习的第二部分要做的。另一种替代方法是创建 svc:/application/pkg/server 服务的另一个实例,如果您需要在同一系统上运行多个 IPS depo 服务器,比如说您希望拥有 Solaris 信息库的一个本地副本(您可以在此找到如何制作副本的说明),并需要一个开发/测试信息库用于自己的代码,这将很有用。我通过一个额外练习说明了这一方法,若您有空可以完成此练习。

示例 3-1 如何创建基于文件系统的信息库

  1. (可选)创建一个 ZFS 文件系统以存放信息库数据。
    $ sudo zfs create <filesystem>
  2. 创建框架信息库并设置信息库的发布者:
    $ sudo pkgrepo create <path to repository>
    $ sudo pkgrepo set -s <path to repository> publisher/prefix=example.com
  3. 验证该信息库已成功创建且已设置发布者:
    $ pkgrepo info -s <path to repository> 
  4. 将新信息库添加到系统映像:
    $ pkg set-publisher -p file:<path to repository>
  5. 验证该信息库工作正常:
    pkg publisher

创建基于文件系统的 IPS 信息库

可以如下所示:

oracle@solaris:~$ pkgrepo create ~/myrepo
oracle@solaris:~$ pkgrepo info -s ~/myrepo
PUBLISHER PACKAGES STATUS           UPDATED
oracle@solaris:~$ pkgrepo set -s ~/myrepo publisher/prefix=example.com
oracle@solaris:~$ pkgrepo info -s ~/myrepo
PUBLISHER   PACKAGES STATUS           UPDATED
example.com 0        online           2011-05-19T11:31:28.549665Z

示例 3-2 如何使用 SMF 创建自己的 IPS 信息库

这是在本地系统上配置更永久的 IPS 信息库服务器的首选方式。最常用的方式是修改 application/pkg/server 服务的默认实例,对此可以使用 svccfg(1M) 命令。但首先需要有个地方存放信息库,为此我们可以创建一个 zfs 文件系统。当我们将更多软件包放入信息库时,信息库将会增长,随着这种增长,我们要对存储进行管理,通过使用 zfs 文件系统而不仅仅是目录,我们在存储管理方法上有更多选择的自由。

  1. 创建一个 ZFS 文件系统以存放信息库数据。
    $ sudo zfs create <filesystem>
  2. 使用 pkgrepo(1) 命令创建框架信息库,并设置发布者。
    $ pkgrepo create <path to repository>

    $ pkgrepo set -s <path repository> publisher/prefix=example.com
  3. 设置端口值。
    $ sudo svccfg -s application/pkg/server setprop pkg/port=port_value
  4. 设置信息库数据的位置值。
    $ sudo svccfg -s application/pkg/server setprop pkg/inst_root=$repository_directory
  5. 刷新信息库服务。
    $ sudo  svcadm refresh application/pkg/server
  6. 启动信息库服务。
    $ sudo  svcadm enable application/pkg/server
  7. 打开浏览器并键入 http://localhost:port_value 以确认已创建信息库,也可以通过运行以下命令验证连通性:
    $ wget http://localhost:<port_value>

使用 SMF 创建 IPS 信息库

首先需要创建一个 ZFS 文件系统来存放信息库,对于本示例,我将使用 /export/ips:

oracle@solaris:~$ sudo zfs create rpool/export/ips
oracle@solaris:~$ sudo zfs create rpool/export/ips/example
eoracle@solaris:~$ zfs list
NAME                       USED  AVAIL  REFER  MOUNTPOINT
rpool                     8.42G  7.20G  92.5K  /rpool
rpool/ROOT                6.14G  7.20G    31K  legacy
rpool/ROOT/solaris        6.14G  7.20G  6.00G  /
rpool/dump                1023M  7.20G  1023M  -
rpool/export               225M  7.20G    36K  /export
rpool/export/home          225M  7.20G    32K  /export/home
rpool/export/home/oracle   225M  7.20G   225M  /export/home/oracle
rpool/export/ips            31K  7.20G    31K  /export/ips
rpool/export/ips/example    31K  7.20G    31K  /export/ips/example  <--- Our new zfs file system
rpool/swap                1.06G  8.10G   172M  -

接下来需要使用 pkgrepo(1) 创建信息库并设置发布者:

oracle@solaris:~$ sudo pkgrepo create /export/ips/example
oracle@solaris:~$ pkgrepo info -s /export/ips/example
PUBLISHER PACKAGES STATUS           UPDATED
oracle@solaris:~$ sudo pkgrepo set -s /export/ips/example publisher/prefix=example.com
oracle@solaris:~$ pkgrepo info -s /export/ips/example
PUBLISHER   PACKAGES STATUS           UPDATED
example.com 0        online           2011-05-19T16:55:14.278173Z

看起来一切顺利,现在需要在 SMF 中将 application/pkg/server 服务的默认实例上的默认端口和位置更改为 10001/export/ips/local。为此,使用 svccfg(1M)svcadm(1M)

oracle@solaris:~$ svcs application/pkg/server
STATE          STIME    FMRI
disabled       11:05:09 svc:/application/pkg/server:default
oracle@solaris:~$ sudo svccfg -s application/pkg/server setprop pkg/port=10001 <---- Set the port to 10001
oracle@solaris:~$ sudo svccfg -s application/pkg/server setprop pkg/inst_root=/export/ips/example <---- rep. location
oracle@solaris:~$ sudo svcadm refresh application/pkg/server
oracle@solaris:~$ sudo svcadm enable application/pkg/server
oracle@solaris:~$ svcs application/pkg/server
STATE          STIME    FMRI
online         10:51:10 svc:/application/pkg/server:default

好了,现在我们将浏览器指向 http://localhost:10001,试试看我们的设置是否起作用

FF SMF Depo

看起来很好,我们保留此信息库,以便用于下面的练习 4。但在这之前,我们来看看如何使用 SMF 命令停止 IPS 信息库服务。为更改服务状态,我们使用 svcadm(1M),正如我们在启动服务时所做的那样。要验证服务的状态,使用 svcs(1M):

oracle@solaris:~$ svcs application/pkg/server
STATE          STIME    FMRI
online         13:03:52 svc:/application/pkg/server:defaul
oracle@solaris:~$ sudo svcadm disable application/pkg/server
oracle@solaris:~$ svcs application/pkg/server
STATE          STIME    FMRI
disabled       13:04:20 svc:/application/pkg/server:default
oracle@solaris:~$ sudo svcadm enable application/pkg/server
oracle@solaris:~$ svcs application/pkg/server
STATE          STIME    FMRI
online         13:04:34 svc:/application/pkg/server:defaul

有关 SMF 的更多信息,可以查看这里:管理服务(概述)

示例 3-3 如何使用 SMF 创建 IPS 信息库服务器的另一个实例(若您有空,可以完成这个额外的练习。)

有时我们可能需要在系统上运行多个 IPS 服务器,比如说在一个服务器上运行开发和测试 IPS 信息库,但还需要 Solaris 信息库的一个本地副本。由于这些是永久性的,所以最好使用 Solaris SMF 以服务形式管理 pkg.depotd 进程。这可以通过向 pkg/server 服务添加新的实例来实现。为此,需要执行以下步骤:

1. 创建一个 ZFS 文件系统以存放信息库数据。
    $ sudo zfs create <filesystem>

2. 使用 pkgrepo(1) 命令创建第一个框架信息库,并设置发布者。前面我们执行过此操作,因此如果您完成了上一示例,可以跳过这一步。
    $ sudo pkgrepo create repository <path to repository>
    $ sudo pkgrepo set -s <path repository> publisher/prefix=<publisher name>

3. 添加新的 pkg/server 服务实例
    $ sudo svccfg -s pkg/server add <instance_name>

    $ sudo scvcfg -s pkg/server:<instance_name> addpg pkg application

    $ sudo svccfg -s pkg/server:<instance_name> addpg general framework

    $ sudo svccfg -s pkg/server:<instance_name> setprop general/complete=astring:\"\"

    $ sudo svccfg -s pkg/server:<instance_name> setprop general/enabled=boolean: true

4. 设置信息库数据的端口和路径值。
    $ sudo svccfg -s pkg/server:<instance_name> setprop pkg/port=<port_value>
    $ sudo svccfg -s pkg/server:<instance_name> setprop pkg/inst_root=<repository_directory>

5. 刷新信息库服务实例。
    $ sudo  svcadm refresh application/pkg/server:<instance_name>

6. 启动信息库实例。
    $ sudo  svcadm enable application/pkg/server:<instance_name>

7. 验证新服务实例运行是否正常
    $ svcs -x application/pkg/server:<instance_name>

8. 打开浏览器并键入 http://localhost:<port_value> 以确认成功创建了信息库。

使用 SMF 创建 IPS 信息库

oracle@solaris:~$ sudo zfs create rpool/export/ips/devtest
oracle@solaris:~$ sudo pkgrepo create /export/ips/devtest
oracle@solaris:~$ sudo pkgrepo set -s /export/ips/devtest publisher/prefix=devtest.example.com
oracle@solaris:~$ sudo svccfg -s pkg/server add devtest
oracle@solaris:~$ sudo svccfg -s pkg/server:devtest addpg pkg application
oracle@solaris:~$ sudo svccfg -s pkg/server:devtest addpg general framework
oracle@solaris:~$ sudo svccfg -s pkg/server:devtest setprop general/complete=astring:\"\"

oracle@solaris:~$ sudo svccfg -s pkg/server:devtest setprop general/enabled=boolean: true
oracle@solaris:~$ sudo svccfg -s pkg/server:devtest setprop pkg/port=10002
oracle@solaris:~$ sudo svccfg -s pkg/server:devtest setprop pkg/inst_root=/export/ips/devtest
oracle@solaris:~$ sudo svcadm refresh pkg/server:devtest
oracle@solaris:~$ sudo  svcadm enable pkg/server:devtest
oracle@solaris:~$ svcs pkg/server
STATE          STIME    FMRI
online         23:24:11 svc:/application/pkg/server:default

online          0:14:46 svc:/application/pkg/server:devtest

正如您最后看到的,现在我们在系统上启动并运行了两个 IPS 信息库,默认服务器在端口 10001,devtest 服务器在端口 10002

总结

现在您已了解如何以基于文件系统的简单信息库和非托管网络信息库的形式创建 IPS 信息库、修改 pkg/server SMF 服务的默认实例,以及最后(若您有空)向 pkg/server SMF 服务添加另一个实例


练习 4:打包一个简单的应用程序并将其提交到 IPS 信息库

预计所需时间:20 分钟

IPS 清单的背景和细节

我们来看看 wget 的清单

这可以使用 pkg contents -m <pkg_name> 来获取

oracle@solaris:~$ pkg contents -m wget > wget_manifest
oracle@solaris:~$ cat wget_manifest
set name=pkg.fmri value=pkg://solaris/web/wget@1.12,5.11-0.175.0.0.0.2.537:20111019T122502Z set name=variant.arch 
    value=i386 value=sparc
set name=info.upstream-url value=http://www.gnu.org/software/wget/ set name=pkg.description 
                           value="GNU wget - a utility to retrieve files from the World Wide Web"
set name=info.classification value=org.opensolaris.category.2008:Applications/Internet
set name=info.source-url value=http://ftp.gnu.org/gnu/wget/wget-1.12.tar.bz2 set name=pkg.summary value="wget - GNU wget"

set name=org.opensolaris.consolidation value=userland
set name=org.opensolaris.arc-caseid value=PSARC/2000/488
license 97a51b7c9fd624f1d16cda23f472e1fbe24d0efc chash=626a60459b65a1cac3a1ce0303c40f3e69403b4c license=GPLv3 
        pkg.csize=12330 pkg.size=35702
depend fmri=pkg:/library/security/openssl@1.0.0.5-0.175.0.0.0.0.525 type=require
depend fmri=pkg:/system/library@0.5.11-0.175.0.0.0.0.0 type=require
depend fmri=pkg:/library/libidn@1.19-0.175.0.0.0.0.525 type=require
dir group=sys mode=0755 owner=root path=etc
dir group=sys mode=0755 owner=root path=usr
dir group=bin mode=0755 owner=root path=usr/bin
dir group=bin mode=0755 owner=root path=usr/sfw
dir group=bin mode=0755 owner=root path=usr/sfw/bin
dir group=sys mode=0755 owner=root path=usr/share

.

file 6be18eb59d8f6906ee4ee18104f3318ae817ee80 chash=17183aaa04fcae20401cec26df325bf66b5d135d elfarch=sparc 
     elfbits=32 elfhash=df980eca224f1e3627dee713590403b359b3084a group=bin mode=0555 owner=root 
     path=usr/bin/wget pkg.csize=211661 pkg.size=506548 variant.arch=sparc

.
.

file 68bc81098633a627d03da5c92ac7e048556460df chash=19c439fc21948815d089487a775b0f72323ca227 elfarch=i386 
     elfbits=32 elfhash=116c3f5c151fabe88e1274a817ad7557ea6bbbb5 group=bin mode=0555 owner=root 
     path=usr/bin/wget pkg.csize=191555 pkg.size=528028 variant.arch=i386
file 291bbb69aa064bb0affa458acb0a1007a178ec13 chash=222ef630db851d7ce5dceae8941dc1c349399ecc 
     facet.doc.info=true group=bin mode=0444 owner=root path=usr/share/info/wget.info pkg.csize=62581 
     pkg.size=199596 restart_fmri=svc:/application/texinfo-update:default variant.arch=i386
.

在结果顶部,可以看到软件包的名称(即 FMRI),包括发布者、类别、名称和版本。我们可以将此清单作为自己的软件包的起点。我们可以设置软件包的一些属性,然后是一些目录操作,其中设置我们将使用的目录的正确权限。这之后是软件包的主要有效负载,即要随该软件包交付的所有文件。

正如您所见到的,对于 wget 软件包我们有两个变体:sparc 和 i386,因此如果您希望同时交付应用程序的 SPARC 和 x86 版本,可在同一软件包中实现,您只需再添加一个“变体”。您还可以看到,wget 将交付同时用于 SPARC 和 x86 平台的 32 位二进制文件。

使用 srm secure rm 的简单示例:

任务

  • 启动本地 IPS 服务器(详情参见练习 3.2)
  • 搭建生成环境
  • 生成清单
  • 发布软件包
  • 检查软件包
  • 通过信息库安装软件包

启动信息库服务器:

有关如何创建和启动本地信息库服务器的详细信息,请参见练习 3.2。

搭建生成环境

在本例中,我们需要安装一个 GNU 基本工具链,对此可通过安装 developer/gnu 软件包来轻松实现,该软件包包含 GNU 开发人员工具链的所有必要工具。这是一个空的软件包,只定义了所有必需的 GNU 开发人员工具的依赖项。因为 IPS 会自动解析依赖关系,我们只需安装此软件包,它所依赖的所有其他软件包都会自动进行安装。这实际上是 IPS 一个非常有用的特性,并且可用于创建软件包的不同“包”。

建立工作区,构建和执行原型安装:

这里的 sourceforge 下载源代码。在下例中我们将使用 srm 1.2.10,这是因为更新的版本 1.2.11 中新的信号处理代码中存在一个错误,不能在 Solaris 上干净地进行编译。

创建工作区和原型区域,您可以在其中创建一个“install”原型。如下所示:

oracle@solaris:~$ cd ~/Work
oracle@solaris:~/Work$ tar -zxf ../Download/srm-1.2.10.tar.gz
oracle@solaris:~/Work$ cd srm-1.2.10
oracle@solaris:~/Work/srm-1.2.10$ mkdir proto_inst
oracle@solaris:~/Work/srm-1.2.10$ ./configure exec_prefix=`pwd`/proto_inst/usr prefix=`pwd`/proto_inst/usr
checking for a BSD-compatible install... /usr/bin/ginstall -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/gnu/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
.
.
config.status: executing depfiles commands

oracle@solaris:~/Work/srm-1.2.10$ make
make  all-recursive
make[1]: Entering directory `/home/oracle/Work/srm-1.2.10'
Making all in lib
make[2]: Entering directory `/home/oracle/Work/srm-1.2.10/lib'
gcc -DHAVE_CONFIG_H -I. -I..     -O2 -DNDEBUG -MT snprintf.o -MD -MP -MF .deps/snprintf.Tpo -c -o snprintf.o snprintf.c
.
.
make[1]: Leaving directory `/home/oracle/Work/srm-1.2.10'
oracle@solaris:~/Work/srm-1.2.10$ make install
.
.
Making install in src
make[1]: Entering directory `/home/oracle/Work/srm-1.2.10/src'
make[2]: Entering directory `/home/oracle/Work/srm-1.2.10/src'
test -z "/home/oracle/Work/srm-1.2.10/proto_inst/usr/bin" || /usr/gnu/bin/mkdir -p "/home/oracle/Work/srm-1.2.10/proto_inst/usr/bin"

  /usr/bin/ginstall -c srm '/home/oracle/Work/srm-1.2.10/proto_inst/usr/bin'
.
.
make[1]: Leaving directory `/home/oracle/Work/srm-1.2.10'
oracle@solaris:~/Work/srm-1.2.10$ ls -R proto_inst/
proto_inst/:
usr
proto_inst/usr:
bin  share
proto_inst/usr/bin:
srm
proto_inst/usr/share:
man
proto_inst/usr/share/man:
man1
proto_inst/usr/share/man/man1:
srm.1
oracle@solaris:~/Work/srm-1.2.10$ ./proto_inst/usr/bin/srm --version
srm (srm) 1.2.10

好了,现在我们在 proto_inst 区域中有一个有效的 srm,下一步将是创建清单,接下来介绍如何完成这一任务:

创建清单:

我们首先使用“pkgsend generate”创建初始的原始清单......

oracle@solaris:~/Work/srm-1.2.10$ pkgsend generate proto_inst > srm_1_2_1_manifest
oracle@solaris:~/Work/srm-1.2.10$ cat srm_1_2_1_manifest
dir group=bin mode=0755 owner=root path=usr timestamp=20110705T162628Z
dir group=bin mode=0755 owner=root path=usr/share timestamp=20110705T162628Z
dir group=bin mode=0755 owner=root path=usr/bin timestamp=20110705T162628Z
dir group=bin mode=0755 owner=root path=usr/share/man timestamp=20110705T162628Z
dir group=bin mode=0755 owner=root path=usr/share/man/man1 timestamp=20110705T162628Z
file usr/share/man/man1/srm.1 group=bin mode=0644 owner=root path=usr/share/man/man1/srm.1 pkg.size=2488
file usr/bin/srm group=bin mode=0755 owner=root path=usr/bin/srm pkg.size=24560

我们来向该清单添加一些元数据。使用文本编辑器,在清单中添加以下 5 行代码

set name=pkg.fmri value=srm@1.2.10,5.11
set name=pkg.description value="Secure rm 1.2.10"
set name=description value="Secure rm"

set name=summary value="Secure rm"
set name=info.classification value="org.opensolaris.category.2008:Applications/System Utilities"

我们需要找出可能有的任何依赖关系,这可以使用“pkgdepend generate”来完成:

oracle@solaris:~/Work/srm-1.2.10$ pkgdepend generate -d ./proto_inst srm_1_2_1_manifest > srm_1_2_1_depend
oracle@solaris:~/Work/srm-1.2.10$ cat srm_1_2_1_depend
depend fmri=__TBD pkg.debug.depend.file=libc.so.1 pkg.debug.depend.path=lib pkg.debug.depend.path=usr/ccs/lib
pkg.debug.depend.path=usr/lib pkg.debug.depend.path=usr/sfw/lib pkg.debug.depend.reason=usr/bin/srm
pkg.debug.depend.type=elf type=require

好了,现在我们知道了有哪些依赖关系,下面来将其解析到软件包。

oracle@solaris:~/Work/srm-1.2.10$ pkgdepend resolve srm_1_2_1_depend
oracle@solaris:~/Work/srm-1.2.10$ ls *.res
srm_1_2_1_depend.res
oracle@solaris:~/Work/srm-1.2.10$ more srm_1_2_1_depend.res
depend fmri=pkg:/system/library@0.5.11-0.151.0.1 type=require

正如您在此所见到的,我们只依赖于一个软件包,因此下面将在清单文件中添加该软件包并设置其格式。

oracle@solaris:~/Work/srm-1.2.10$ cat srm_1_2_1_depend.res >> srm_1_2_1_manifest

oracle@solaris:~/Work/srm-1.2.10$ pkgfmt srm_1_2_1_manifest
oracle@solaris:~/Work/srm-1.2.10$ more srm_1_2_1_manifest
set name=pkg.fmri value=srm@1.2.10,5.11set name=pkg.description value="Secure rm 1.2.10"
set name=description value="Secure rm"
set name=info.classification \
    value="org.opensolaris.category.2008:Applications/System Utilities"

set name=summary value="Secure rm"
dir path=usr group=bin mode=0755 owner=root timestamp=20110705T162628Z
dir path=usr/bin group=bin mode=0755 owner=root timestamp=20110705T162628Z
dir path=usr/share group=bin mode=0755 owner=root timestamp=20110705T162628Z
dir path=usr/share/man group=bin mode=0755 owner=root \
    timestamp=20110705T162628Z
dir path=usr/share/man/man1 group=bin mode=0755 owner=root \
    timestamp=20110705T162628Z
file usr/bin/srm path=usr/bin/srm group=bin mode=0755 owner=root \
    pkg.size=24560
file usr/share/man/man1/srm.1 path=usr/share/man/man1/srm.1 group=bin \
    mode=0644 owner=root pkg.size=2488
depend fmri=pkg:/system/library@0.5.11-0.151.0.1 type=require



好了,现在我们有一个漂亮的清单文件,可以用它来发布软件包。

在清单中进行以下编辑:

1) 将“dir path=usr/share”的权限调整为“group=sys”。

2) 将“dir path=usr”的权限调整为“group=sys”。

如果您不执行以上两个步骤,此软件包的安装将失败,因为在该软件包的安装过程中,IPS 将验证列出的权限并将确定此清单中的列表提示从 Solaris 11 提供的那些软件包中剔除。

3) 最后,将清单文件重命名,为其添加“.p5m”扩展名

发布软件包:

我们需要告诉 SMF 我们的信息库应为读/写而非(如默认那样)只读

oracle@solaris:~/Work/srm-1.2.10$ sudo svccfg -s pkg/server setprop pkg/readonly=false
oracle@solaris:~/Work/srm-1.2.10$ sudo svcadm refresh pkg/server:default

oracle@solaris:~/Work/srm-1.2.10$ sudo svcadm restart pkg/server:default
oracle@solaris:~/Work/srm-1.2.10$ svcprop -p pkg/readonly pkg/server:default
false

oracle@solaris:~/Work/srm-1.2.10$

为发布软件包,我们使用“pkgsend publish”:


oracle@solaris:~/Work/srm-1.2.10$ sudo pkgsend publish -d ./proto_inst -s /export/ips/example \
srm_1_2_1_manifest.p5m
pkg://example.com/srm@1.2.10,5.11:20111117T63324Z 
PUBLISHED

我们将其直接发布到信息库所在的文件系统。发布之后,重新启动服务以验证是否存在该软件包:

oracle@solaris:~/Work/srm-1.2.10$ sudo svcadm disable pkg/server:default
oracle@solaris:~/Work/srm-1.2.10$ sudo svcadm enable pkg/server:default

oracle@solaris:~/Work/srm-1.2.10$ pkgrepo info -s http://localhost:10001 PUBLISHER   PACKAGES STATUS           UPDATED
example.com 1        online           2011-11-17T17:43:48.638470Z

好了,现在我们在本地信息库中发布了 srm 软件包,下面来试试是否可以安装它。

安装软件包:

我们首先要将本地信息库添加到映像中,之后可以尝试从本地信息库安装 srm。

oracle@solaris:~$ pkg publisher
PUBLISHER                             TYPE     STATUS   URI
solaris                  (preferred)  origin   online   http://pkg.oracle.com/solaris/release/ example.com                          
                                      origin   online   file:/export/home/oracle/myrepo/
oracle@solaris:~$ sudo pkg unset-publisher example.com
oracle@solaris:~$ sudo pkg set-publisher -p http://localhost:10001 pkg set-publisher:
  Added publisher(s): example.com
oracle@solaris:~$ pkg publisher
PUBLISHER                             TYPE     STATUS   URI
solaris                  (preferred)  origin   online   http://pkg.oracle.com/solaris/release/  example.com                          
                                      origin   online   http://localhost:10001/

oracle@solaris:~$ pkg info -r srm
          Name: utilities/srm
       Summary: Secure rm
   Description: Secure rm 1.2.10
      Category: Applications/System Utilities
         State: Not installed
     Publisher: example.com
       Version: 1.2.10
 Build Release: 5.11
        Branch: 0.1
Packaging Date: July  5, 2011 05:43:48 PM
          Size: 26.41 kB
          FMRI: pkg://example.com/utilities/srm@1.2.10,5.11-0.1:20110705T174348Z

oracle@solaris:~$ sudo pkg install srm
               Packages to install:     1
           Create boot environment:    No
DOWNLOAD                                  PKGS       FILES    XFER (MB)
Completed                                  1/1         2/2      0.0/0.0

PHASE                                        ACTIONS
Install Phase                                  13/13

PHASE                                          ITEMS
Package State Update Phase                       1/1
Image State Update Phase                         2/2

PHASE                                          ITEMS
Reading Existing Index                           8/8
Indexing Packages                                1/1
oracle@solaris:~$ srm --version
srm (srm) 1.2.10

总结

现在,您应基本了解了如何创建自己的 IPS 信息库以及如何将软件包发布到该信息库。